package de.mfits.fireflyplayer.service;

import java.io.IOException;

import net.firefly.client.model.data.Song;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.IBinder;
import android.util.Log;
import de.mfits.fireflyplayer.PlaybackActivity;
import de.mfits.fireflyplayer.R;
import de.mfits.fireflyplayer.storage.DbHelper;

public class PlaybackServiceImpl extends Service {

  private final MediaPlayer player = new MediaPlayer();
  private final DbHelper dbHelper = new DbHelper(this);

  @Override
  public void onCreate() {
    super.onCreate();
    player.setOnPreparedListener(new OnPreparedListener() {
      @Override
      public void onPrepared(MediaPlayer mp) {
        player.start();
      }
    });
    player.setOnCompletionListener(new OnCompletionListener() {
      @Override
      public void onCompletion(MediaPlayer mp) {
        hideNotification();
      }
    });
    player.setOnErrorListener(new OnErrorListener() {
      @Override
      public boolean onError(MediaPlayer mp, int what, int extra) {
        return true;
      }
    });
  }

  @Override
  public void onDestroy() {
    super.onDestroy();
    if (player.isPlaying()) {
      player.stop();
    }
  }

  @Override
  public IBinder onBind(Intent intent) {
    return PlaybackService.bindService(this);
  }

  boolean play(int id) {
    showNotification(id);

    // We don't want the service to end after the UI unbinds
    startService(new Intent(this, PlaybackServiceImpl.class));

    if (player.isPlaying()) {
      player.stop();
    }

    try {
      player.reset();
      player.setDataSource("http://data.forster.priv:3689/rsp/stream/" + id);
    } catch (IllegalArgumentException e) {
      Log.e(getClass().getSimpleName(), e.getMessage(), e);
    } catch (IllegalStateException e) {
      Log.e(getClass().getSimpleName(), e.getMessage(), e);
    } catch (IOException e) {
      Log.e(getClass().getSimpleName(), e.getMessage(), e);
    }

    player.prepareAsync();

    return true;
  }

  void stop() {
    if (player.isPlaying()) {
      player.stop();
    }
    hideNotification();

    stopSelf();
  }

  private void showNotification(int id) {
    Song song = dbHelper.loadSong(id);
    String title = song.getTitle();
    String content = song.getArtist();
    String album = song.getAlbum();
    if (album.length() > 0) {
      content += " - " + album;
    }

    NotificationManager notificationManager =
        (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    Notification notification =
        new Notification(R.drawable.notification, null, System.currentTimeMillis());
    PendingIntent pi = PendingIntent.getActivity(this, 0, new Intent(PlaybackActivity.ACTION), 0);
    notification.setLatestEventInfo(this, title, content, pi);
    notification.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;
    notificationManager.notify(0, notification);
  }

  private void hideNotification() {
    ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).cancelAll();
  }

  public int getDuration() {
    return player.getDuration();
  }

  public int getCurrentPosition() {
    return player.getCurrentPosition();
  }

  public void start() {
    player.start();
  }

  public void pause() {
    player.pause();
  }

  public boolean isPlaying() {
    return player.isPlaying();
  }

  public void seekTo(int pos) {
    player.seekTo(pos);
  }

  public void setLooping(boolean looping) {
    player.setLooping(looping);
  }

  public void setVolume(float leftVolume, float rightVolume) {
    player.setVolume(leftVolume, rightVolume);
  }
}
